CloudWatchのカスタムメトリクスでJavaVMのGC関連情報を取得
JavaVMのGC情報を取得します
前回はLinuxOSのメモリー関連情報を取得して、CloudWatchに登録しました。今回は、JavaVMのガベージコレクション周りの情報をCloudWatchに登録したいと思います。
環境の構築
今回は、JavaVMのGCを見るためにTomcatをインストールします。また、JREではなくJDKを利用しますので必要なものをインストールします。CloudWatchコマンドラインツールは設定済みとします。詳しくは前回の記事をご覧ください。JREではなくJDKを入れる理由は、jpsコマンドとjstatコマンドを使うためです。これらのコマンドはプロセスIDなどを取得するためsudoで実行します。
$ sudo yum install java-1.6.0-openjdk-devel $ sudo alternatives --install /usr/bin/java java /usr/lib/jvm/java-1.6.0/bin/java 200 $ sudo alternatives --config java 3 プログラムがあり 'java' を提供します。 選択 コマンド ----------------------------------------------- *+ 1 /usr/lib/jvm/jre-1.6.0-openjdk/bin/java 2 /usr/lib/jvm/jre-1.5.0-gcj/bin/java 3 /usr/lib/jvm/java-1.6.0/bin/java Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:3 $ sudo yum install tomcat6 $ sudo service tomcat6 start
jpsコマンド
TomcatのプロセスIDを取得するにはjpsコマンドを用います。
sudo jps -J-Djava.io.tmpdir=/usr/share/tomcat6/temp 19660 Jps 19246 Bootstrap
Bootstrapと出ている行がTomcatのプロセスIDです。これを前回と同じように成型してプロセスIDだけ取得します。
sudo jps -J-Djava.io.tmpdir=/usr/share/tomcat6/temp | grep 'Bootstrap' | tr -s ' ' | cut -d ' ' -f 1 19246
取れました!
jstatコマンド
TomcatのプロセスIDを用いてJavaVMの統計情報を取得します。
$ sudo jstat -J-Djava.io.tmpdir=/usr/share/tomcat6/temp -gcutil 19246 S0 S1 E O P YGC YGCT FGC FGCT GCT 0.00 0.00 6.14 28.70 68.77 5 0.020 3 0.087 0.106
いつものように成型します。
$ sudo jstat -J-Djava.io.tmpdir=/usr/share/tomcat6/temp -gcutil 20191 | tail -1 | tr -s ' ' | cut -c2-100 0.00 0.00 6.14 28.70 68.77 5 0.020 3 0.087 0.1
さらにここから1つ目、2つ目と値を取得していきます。これで値の取得ができました。
bashでシェルを書く
一連の操作を行うシェルを書きます。jvm_gc_report.sh という名前で保存しました。
#!/bin/bash export AWS_CLOUDWATCH_HOME=/home/ec2-user/CloudWatch-1.0.12.1 export AWS_CREDENTIAL_FILE=$AWS_CLOUDWATCH_HOME/credentials export AWS_CLOUDWATCH_URL=https://monitoring.amazonaws.com export PATH=$AWS_CLOUDWATCH_HOME/bin:$PATH export JAVA_HOME=/usr/lib/jvm/java-1.6.0/ # get ec2 instance id instanceid=`wget -q -O - http://169.254.169.254/latest/meta-data/instance-id` bootstrappid=`jps -J-Djava.io.tmpdir=/usr/share/tomcat6/temp | grep 'Bootstrap' | tr -s ' ' | cut -d ' ' -f 1` jstat=`jstat -J-Djava.io.tmpdir=/usr/share/tomcat6/temp -gcutil $bootstrappid | tail -1 | tr -s ' ' | cut -c2-100` survivor0=`echo $jstat|cut -d ' ' -f 1` survivor1=`echo $jstat|cut -d ' ' -f 2` eden=`echo $jstat|cut -d ' ' -f 3` old=`echo $jstat|cut -d ' ' -f 4` permanent=`echo $jstat|cut -d ' ' -f 5` young=`echo $jstat|cut -d ' ' -f 6` youngtime=`echo $jstat|cut -d ' ' -f 7` fgc=`echo $jstat|cut -d ' ' -f 8` fgctime=`echo $jstat|cut -d ' ' -f 9` gct=`echo $jstat|cut -d ' ' -f 10` mon-put-data --metric-name "Survivor0" --namespace "Java/Tomcat" --dimensions "InstanceId=$instanceid" --value "$survivor0" --unit "Percent" --region ap-northeast-1 mon-put-data --metric-name "Survivor1" --namespace "Java/Tomcat" --dimensions "InstanceId=$instanceid" --value "$survivor1" --unit "Percent" --region ap-northeast-1 mon-put-data --metric-name "Eden" --namespace "Java/Tomcat" --dimensions "InstanceId=$instanceid" --value "$eden" --unit "Percent" --region ap-northeast-1 mon-put-data --metric-name "Old" --namespace "Java/Tomcat" --dimensions "InstanceId=$instanceid" --value "$old" --unit "Percent" --region ap-northeast-1 mon-put-data --metric-name "Permanent" --namespace "Java/Tomcat" --dimensions "InstanceId=$instanceid" --value "$permanent" --unit "Percent" --region ap-northeast-1 mon-put-data --metric-name "YoungGC" --namespace "Java/Tomcat" --dimensions "InstanceId=$instanceid" --value "$young" --unit "Count" --region ap-northeast-1 mon-put-data --metric-name "YoungGCTime" --namespace "Java/Tomcat" --dimensions "InstanceId=$instanceid" --value "$youngtime" --unit "Seconds" --region ap-northeast-1 mon-put-data --metric-name "FullGC" --namespace "Java/Tomcat" --dimensions "InstanceId=$instanceid" --value "$fgc" --unit "Count" --region ap-northeast-1 mon-put-data --metric-name "FullGCTime" --namespace "Java/Tomcat" --dimensions "InstanceId=$instanceid" --value "$fgctime" --unit "Seconds" --region ap-northeast-1 mon-put-data --metric-name "TotalGCTime" --namespace "Java/Tomcat" --dimensions "InstanceId=$instanceid" --value "$gct" --unit "Seconds" --region ap-northeast-1
実行して何もエラーが表示されなければ成功です。
cronに登録する
今回のシェルはroot権限で実行する必要がありますので、rootユーザのcronに登録します。
$ sudo crontab -e
中身はこんな感じです。
*/5 * * * * /home/ec2-user/custom_metrics_report.shi */5 * * * * /home/ec2-user/jvm_gc_report.sh
AWS Management Consoleで動作結果を確認する
最後に実行結果を見てみます。
まとめ
jpsとjstatを用いてJavaVMのGC情報を取得することができ、これをCloudWatchに登録することで、EC2インスタンスの外側からTomcatがどのように動いているか知る事ができました。カスタムメトリクスで楽々運用生活を手に入れましょう!
参考資料
jps and jstat for tomcat on jdk-1.6.0_24
CloudWatchのカスタムメトリクスでFreeMemoryMBytes、UsedMemoryPercent、LoadAverage、Stealを取得